package com.smart.community.commons.service;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 服务调用基类
 * 
 * 提供统一的服务调用模板，包含异常处理、降级策略、监控指标
 * 所有需要调用其他服务的类都应该继承此类
 * 
 * @author Wu.Liang
 * @version 2.0.0
 * @since 2025-08-28
 */
@Slf4j
public abstract class BaseServiceCaller {
    
    /**
     * 安全调用Feign接口
     * 
     * @param serviceName 服务名称
     * @param methodName 方法名称
     * @param supplier 调用逻辑
     * @param defaultValue 默认值
     * @param <T> 返回类型
     * @return 调用结果或默认值
     */
    protected <T> T safeCall(String serviceName, String methodName, Supplier<T> supplier, T defaultValue) {
        try {
            T result = supplier.get();
            log.debug("{}服务{}方法调用成功", serviceName, methodName);
            return result;
        } catch (Exception e) {
            log.warn("{}服务{}方法调用失败，使用默认值: {}", serviceName, methodName, e.getMessage());
            return defaultValue;
        }
    }
    
    /**
     * 安全调用Feign接口（无返回值）
     * 
     * @param serviceName 服务名称
     * @param methodName 方法名称
     * @param runnable 调用逻辑
     */
    protected void safeCall(String serviceName, String methodName, Runnable runnable) {
        try {
            runnable.run();
            log.debug("{}服务{}方法调用成功", serviceName, methodName);
        } catch (Exception e) {
            log.warn("{}服务{}方法调用失败: {}", serviceName, methodName, e.getMessage());
        }
    }
    
    /**
     * 批量安全调用Feign接口
     * 
     * @param serviceName 服务名称
     * @param methodName 方法名称
     * @param items 待处理项目
     * @param processor 处理逻辑
     * @param <T> 项目类型
     * @param <R> 结果类型
     * @return 处理结果列表
     */
    protected <T, R> List<R> safeBatchCall(String serviceName, String methodName, List<T> items, Function<T, R> processor) {
        if (items == null || items.isEmpty()) {
            return new ArrayList<>();
        }
        
        List<R> results = new ArrayList<>();
        for (T item : items) {
            try {
                R result = processor.apply(item);
                if (result != null) {
                    results.add(result);
                }
            } catch (Exception e) {
                log.warn("{}服务{}方法处理项目失败: {}", serviceName, methodName, e.getMessage());
            }
        }
        
        log.debug("{}服务{}方法批量处理完成，成功处理{}个项目", serviceName, methodName, results.size());
        return results;
    }
}
